package cn.hit.thread;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JProgressBar;
import javax.swing.JTextArea;

import cn.hit.constant.HitConstants;
import cn.hit.utils.HitUtils;

public class ExportFileBySVNNumberThread extends Thread {

    // 源文件根路径
    private String root;

    // 要输出到那个文件夹下面
    private String targetDir;

    // 要依照的版本号
    private int referNumber;

    // 查找到文件存放的容器
    private List<File> fileContainer = new ArrayList<File>();

    private JTextArea logArea;
    private JProgressBar pbar;
    private StringBuilder failLog;
    private StringBuilder exportLog;
    /**
     * 通过版本号查找文件并输出
     * 
     * @param root：源文件根路径
     * @param targetDir：要把查找到的文件输出的路径
     * @param referNumber：参照版本号
     */
    public ExportFileBySVNNumberThread(String root, String targetDir, int referNumber,JTextArea logArea,JProgressBar pbar) {
        this.root = root;
        this.targetDir = targetDir;
        this.referNumber = referNumber;
        this.logArea = logArea;
        this.pbar = pbar;
        failLog = new StringBuilder();
        exportLog = new StringBuilder();
    }

    /**
     * 查找路径下所有符合规则的文件，并把它放到fileContainer里面
     * 
     * @param fileContainer
     * @param path
     */
    private void searchFile(List<File> fileContainer, String path) {
        File currentFile = new File(path);
        File[] childFiles = currentFile.listFiles();
        try {
            for (int i = 0; i < childFiles.length; i++) {
                if (childFiles[i].getName().equals(".svn")) {
                    BufferedReader reader = new BufferedReader(new InputStreamReader(
                            new FileInputStream(new File(childFiles[i].getAbsolutePath()
                                    + "\\all-wcprops")), HitConstants.FILE_ENCODING));
                    String tmpStr;
                    while ((tmpStr = reader.readLine()) != null) {
                        tmpStr = URLDecoder.decode(tmpStr, HitConstants.FILE_ENCODING);
                        if (tmpStr.startsWith("/svn/source/!svn/ver/")) {
                            String[] folderNames = tmpStr.split("/");
                            int tmpNumber = Integer.valueOf(folderNames[5]);
                            if (tmpNumber >= referNumber) {
                                String filepath = root.substring(0, root.lastIndexOf("\\"))
                                        + tmpStr.substring(tmpStr.indexOf(folderNames[5])
                                                + folderNames[5].length(), tmpStr.length());
                                filepath = filepath.replace("/", "\\");
                                File file = new File(filepath);
                                if (file.isFile()) {
                                    fileContainer.add(file);
                                }
                            }
                        }
                    }
                    reader.close();
                }
                if (childFiles[i].isDirectory() && !childFiles[i].isHidden()) {
                    searchFile(fileContainer, childFiles[i].getCanonicalPath());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 执行输出文件操作
     */
    @SuppressWarnings("static-access")
    public void exportFile() {
        searchFile(fileContainer, root);
        int successCount = 0;
        int failCount = 0;
        pbar.setMaximum(fileContainer.size());
        pbar.setVisible(true);
        OutputStream ops = null;
        InputStream ips = null;
        logArea.setText("");
        String path = null;
        for (File file : fileContainer) {
            try {
                exportLog.append(file.getAbsolutePath());
                String printedText = null;
                if (successCount > HitConstants.LOG_ROLL_LINE_SIZE) {
                    printedText = logArea.getText()
                            .substring(logArea.getText().indexOf("......") + 7,
                                    logArea.getText().length());
                } else {
                    printedText = logArea.getText();
                }
                path = file.getAbsolutePath();
                logArea
                        .setText(printedText + "正在执行导出SVN文件："
                                + path.substring(path.lastIndexOf("/") + 1, path.length())
                                + "......\n");
                String iFilePath = file.getAbsolutePath();
                String oFilePath = targetDir
                        + "\\SVN\\"
                        + iFilePath.substring(iFilePath.indexOf(root.substring(root
                                .lastIndexOf("\\"), root.length())) + 1, iFilePath.length());
                File exportFile = new File(oFilePath);
                if (!exportFile.getParentFile().exists()) {
                    exportFile.getParentFile().mkdirs();
                }
                ips = new FileInputStream(file);
                ops = new FileOutputStream(exportFile);
                byte[] buffer = new byte[ips.available()];
                ips.read(buffer);
                ops.write(buffer);
                ips.close();
                ops.close();
            } catch (Exception e) {
                failLog.append("失败导出SVN文件:" + file.getAbsolutePath() + "\n");
                failCount++;
                e.printStackTrace();
                exportLog.append("**********导出SVN失败\n\t" + e.toString());
            }
            successCount++;
            exportLog.append("**********导出SVN完成\n");
            pbar.setValue(successCount + failCount);
            try {
                this.sleep(HitConstants.DEFER_SLEEP_TIME/2);
            } catch (InterruptedException e) {
                logArea.setText("************************非正常结束************************");
                exportLog.append(logArea.getText());
                e.printStackTrace();
            }
        }
        if (successCount <= 0) {
            logArea.setText("************************非法SVN文件************************");
        } else {
            logArea.setText("************************执行导出SVN文件完成************************\n"
                    + "成功导出SVN文件数量:" + successCount + "\n" + failLog.toString());
        }
        pbar.setVisible(false);
        HitUtils.exportLogFile(targetDir, "导出SVN文件日志", exportLog.toString());
    }

    @Override
    public void run() {
        exportFile();
    }

}
